using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System;

namespace KFGame
{
    /// <summary>
    /// 事件模板类
    /// </summary>
    public class EventModel
    {
        //输出 输入  接口名,指接口配置中的名字
        public string com = "COM1";
        //启动  读取模型，开启后，载入后加入到侦听器， 写模型，开启后，启动就发送一次
        public bool enter = false;
        //输出 输入  标签
        public int tag = 1;
        //输出  write 输入 read
        public string type = "read";
        //输出  名字  输入 名字
        public string name = "coin";
        //输出  发送模式  输入 接收过
        public byte dataType = 0x01;
        //输出  输出模板排序位置  输入 过虑位置
        public uint dataIndex = 1;
        //输出  数据长度  输入 数据长度
        public uint dataLength = 1;
        //输出  实体数据
        public byte[] checkdata = new byte[1];
        //输出 模板数据体
        public byte[] templateData = new byte[1];
        //输出 次数
        public int sendnumber = 0;
        //输出  持续时间
        public double sendtime = 0.2f;
        //输出 接收过虑器名  以接收进行计次
        public string fiterName = "";

        //是否有停止信号， 止操作只针对：需要发送一些数据才能让设备停止的行为使用
        public bool isEnd = false;
        //停止信号数据体 如启动停止信号， 调用停止信号事件
        public string EndDataName = "";
    }

    /// <summary>
    /// Seral Port 对象
    /// </summary>
    public class KFSeralPortObject : MonoBehaviour
    {

        public static bool isInitialize = false;
        public static KFSeralPortObject spobject;
        public static KFSeralPortObject Initialize()
        {
            if (isInitialize)
                return spobject;

            isInitialize = true;
            var g = new GameObject("KF_SeralPort");
            spobject = g.AddComponent<KFGame.KFSeralPortObject>();
            // KF.Instantiation().MoveGameObjectToScene(g);
            g.AddComponent<KFGame.KFSeralPortToEvent>();
            DontDestroyOnLoad(g);
            return spobject;
        }
        void Update()
        {
            foreach (var item in KFSeralPort.seralPorCs)
                item.Value.update();
        }
        void OnDestroy()
        {
            KFSeralPort.CloseALL();
        }

    }

    /// <summary>
    /// com 串口处理工具， 使用多线程收发信息，多com接口处理
    /// </summary> 
    public class KFSeralPort
    {
        [System.Flags]
        public enum FormatType
        {
            Default = 0x00,
            //固定长度
            FixedLength = 0x01,
            //固定开始
            FixedStart = 0x02,
            //固定结束
            FixedEnd = 0x04,
            //包函数据长度位
            EnvelopeLength = 0x08,
            //包函校验类型
            EnvelopeCRC = 0x10,
            //发送数据时强制校验数据
            SendParity = 0x20

        };

        ///接口对象
        private SerialPort sp;
        //名称
        public string name = "com0";
        //接口名称
        public string comName = "com1";
        //比特率
        public int baudRate = 9600;
        // 停止位
        public StopBits stopBits = StopBits.One;
        //停止位
        public int stopBitsData = 1;
        //校验位
        public Parity parity = Parity.None;
        //校验位
        public int parityData = 0;
        //数据位
        public int dataBits = 8;
        //运行状态
        bool isEnter = true;

        //通信数据格式类型 
        public byte dataFormatType = (byte)(FormatType.FixedLength | FormatType.FixedStart | FormatType.FixedEnd);
        //通信数据格式固定长度（dataFormatType 确定是否计算长度）
        public int DataFormatLangth = 24;
        //通信数据格式固定开始（dataFormatType 确定是否计算）
        public byte DataFormatStart = 0xAC;
        //通信数据格式固定结束（dataFormatType 确定是否计算）
        public byte DataFormatEnd = 0xCD;
        //通信数据格式数据长度值所在位 （dataFormatType 确定是否计算）
        public int DataFormatSizeIndex = 1;
        //通信数据格式 校验方式 （dataFormatType 确定是否计算）
        public string DataFormatParityType = "CRC_HL";
        //通信数据格式，发送数包时需要加校检
        public string DataFormatSendParity = "CRC_HL";


        //接口列表
        public static Dictionary<string, KFSeralPort> seralPorCs = new Dictionary<string, KFSeralPort>();
        //接口配置地址
        public static string iniPath = Application.streamingAssetsPath + "/KFConfig/kfseralportconfig.ini";
        //事件定义模板
        public static string eventPath = Application.streamingAssetsPath + "/KFConfig/kfseralportevents.ini";
        
        //启试模式
        public static bool isDebug = false;


        /// <summary>
        /// 私有化防构造
        /// </summary>
        /// <param name="namec"></param>
        protected KFSeralPort(string namec = "")
        {
            if (isDebug)
                Debug.Log("Debug mode ->SeralPor create " + namec);

            KFSeralPortObject.Initialize();

            name = namec;
            if (!seralPorCs.ContainsKey(name))
                seralPorCs.Add(name, this);
        }

        /// <summary>
        ///  取得一个模板
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static EventModel getEventMode(string name)
        {
            foreach (var e in eventsModes)
                if (e.name == name)
                    return e;
            return null;
        }

        private static List<EventModel> eventsModes = new List<EventModel>();


        /// <summary>
        /// 自动发送 对象
        /// </summary>
        /// <param name="m"></param>
        private void autoSend(EventModel m)
        {

            OutputData data = new OutputData(m);
            addSend(data);
        }

        /// <summary>
        /// 加载自动侦听器
        /// </summary>
        public void loadRunEvent()
        {
            foreach (var item in eventsModes)
            {

                if (!item.enter)
                    continue;

                if (item.type == "write")
                {
                    autoSend(item);
                    continue;
                }
                if (item.type != "read")
                    continue;

                DataFiter df = new DataFiter(item);
                addFiter(df);

            }
        }


        /// <summary>
        /// 加载事件表
        /// </summary>
        public static void loadEvent()
        {
            //只加载一次
            if (eventsModes.Count > 0)
                return;

            INIParser iNIParser = new INIParser();
            iNIParser.Open(eventPath);
            foreach (var item in iNIParser.SectionNames())
            {
                EventModel template = new EventModel();
                template.com = iNIParser.ReadValue(item, "com", "COM1");
                template.enter = iNIParser.ReadValue(item, "enter", false);
                template.tag = iNIParser.ReadValue(item, "tag", 0);
                template.type = iNIParser.ReadValue(item, "type", "read");
                template.name = iNIParser.ReadValue(item, "name", "event");
                string formatType = iNIParser.ReadValue(item, "dataType", "00");
                template.dataType = Convert.ToByte(formatType.Substring(0, 2), 16);
                template.dataIndex = (uint)iNIParser.ReadValue(item, "dataIndex", 1);
                template.dataLength = (uint)iNIParser.ReadValue(item, "dataLength", 1);
                string checkdatastr = iNIParser.ReadValue(item, "checkdata", "00");
                template.checkdata = DataFiter.S16BStringToBytes(checkdatastr);
                string templateDatastr = iNIParser.ReadValue(item, "templateData", "00");
                template.templateData = DataFiter.S16BStringToBytes(templateDatastr);
                template.sendnumber = iNIParser.ReadValue(item, "sendnumber", 0);
                template.sendtime = iNIParser.ReadValue(item, "sendtime", 0.1);
                template.fiterName = iNIParser.ReadValue(item, "fiterName", "");
                template.isEnd = iNIParser.ReadValue(item, "isEnd", false);
                template.EndDataName = iNIParser.ReadValue(item, "EndDataName", "");
                eventsModes.Add(template);
            }
        }

        /// <summary>
        /// 加载配置
        /// </summary>
        public static void loadConfig()
        {
            INIParser iNIParser = new INIParser();
            iNIParser.Open(iniPath);
            foreach (var item in iNIParser.SectionNames())
            {
                if (!iNIParser.ReadValue(item, "enter", false))
                    continue;

                string name = iNIParser.ReadValue(item, "name", "COM1");

                if (seralPorCs.ContainsKey(name))
                    continue;

                KFSeralPort sc = new KFSeralPort(name);
                sc.comName = iNIParser.ReadValue(item, "comName", "");
                sc.baudRate = iNIParser.ReadValue(item, "baudRate", 9600);
                sc.dataBits = iNIParser.ReadValue(item, "dataBit", 8);
                sc.stopBitsData = iNIParser.ReadValue(item, "parity", 0);
                sc.parityData = iNIParser.ReadValue(item, "stopBit", 1);

                try
                {
                    string formatType = iNIParser.ReadValue(item, "formatType", "01");
                    sc.dataFormatType = Convert.ToByte(formatType.Substring(0, 2), 16);

                    int formatLangth = iNIParser.ReadValue(item, "formatLangth", 24);
                    sc.DataFormatLangth = formatLangth;

                    string formatStart = iNIParser.ReadValue(item, "formatStart", "AC");
                    sc.DataFormatStart = Convert.ToByte(formatStart.Substring(0, 2), 16);

                    string formatEnd = iNIParser.ReadValue(item, "formatEnd", "CD");
                    sc.DataFormatEnd = Convert.ToByte(formatEnd.Substring(0, 2), 16);

                    int formatSizeIndex = iNIParser.ReadValue(item, "formatSizeIndex", 1);
                    sc.DataFormatSizeIndex = formatSizeIndex;

                    string formatParity = iNIParser.ReadValue(item, "formatParity", "md5");
                    sc.DataFormatParityType = formatParity;

                    string sendParity = iNIParser.ReadValue(item, "formatSendParity", "CRC_HL");
                    sc.DataFormatSendParity = sendParity;
                }
                catch (Exception e)
                {
                    Debug.LogError("KF load seralport config 读取配置数据发生错误：" + e.ToString());
                }

                if (isDebug)
                    Debug.Log("[KF debug mode] -> [load seralport config] " + name + "->" + sc.comName + "->" + sc.baudRate);
            }
            iNIParser.Close();

            if (isDebug)
                Debug.Log("[KF debug mode] -> [load seralport config] end ");

        }

        /// <summary>
        /// 初始化配置 在应用启动装载
        /// </summary>
        public static void init()
        {
            CloseALL();

            if (isDebug)
                Debug.Log("[KF debug mode] : Seralport init");

            loadEvent();

            loadConfig();

        }

        /// <summary>
        ///  取得对象 
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>    
        public static KFSeralPort GetSeralPort(string name)
        {
            if (seralPorCs.ContainsKey(name))
                return seralPorCs[name];

            return new KFSeralPort(name);
        }


        //是否连接
        public bool IsConnected
        {
            get { return sp != null && sp.IsOpen; }
        }

        //打开接口
        public void open()
        {

            if (isDebug)
                Debug.Log("[KF Debug mode] ->SeralPor to open " + name + ":" + comName);

            //先关闭
            Close();

            sp = new SerialPort();
            //接口名字，设备连接的名字
            sp.PortName = comName;
            //比特率
            sp.BaudRate = baudRate;
            //校验位
            sp.Parity = parity;
            //数据位
            sp.DataBits = dataBits;
            //停止位
            sp.StopBits = stopBits;
            //获取或设置读取操作未完成时发生超时之前的毫秒数
            sp.ReadTimeout = 100;
            //获取或设置一个值，该值指示在串行通信中是否启用请求发送 (RTS) 信号
            sp.RtsEnable = true;
            //获取或设置一个值，该值在串行通信过程中启用数据终端就绪 (DTR) 信号
            //sp.DtrEnable = true;
            //DsrHolding 获取数据设置就绪 (DSR) 信号的状态
            //ReadBufferSize 获取或设置 SerialPort 输入缓冲区的大小
            sp.ReadBufferSize = 1024;
            //ReceivedBytesThreshold 获取或设置 DataReceived 事件发生前内部输入缓冲区中的字节数
            // sp.ReceivedBytesThreshold = 22;
            //WriteBufferSize 获取或设置串行端口输出缓冲区的大小
            sp.WriteBufferSize = 1024;
            //获取或设置写入操作未完成时发生超时之前的毫秒数
            sp.WriteTimeout = 500;

            sp.ErrorReceived += HandleErrorReceived;
            // sp.DataReceived += new SerialDataReceivedEventHandler (SerialPort_DataReceived);
            // sp.DataReceived += comm_DataReceived;

            try
            {
                if (!IsConnected)
                    sp.Open();
            }
            catch (Exception e)
            {
                if (isDebug)
                    Debug.LogWarning(e.ToString());

            }

            isEnter = true;

            if (IsConnected)
                if (isDebug)
                    Debug.Log("[KF Debug mode] ->SeralPort   is open " + name + ":" + comName);

            //运行自动侦听器
            loadRunEvent();

            //处理线程初始化
            ThreadInit();
        }




        //写入数据
        public void write(byte[] datas)
        {
            writerDatas.Add(datas);

        }

        //检测读取字节是否存在
        public bool checkData(ref byte data, int index = 0)
        {
            if (readDatas.Count <= index)
                return false;

            data = (byte)readDatas[index];
            return true;
        }
        //能读取的数据长度
        public int canReadCont()
        {
            return readDatas.Count;

        }
        //清空数据
        public void clearDatas()
        {
            readDatas.Clear();
        }
        //跳过数据
        public void skipDatas(int langth = 1)
        {
            if (langth >= readDatas.Count)
            {
                readDatas.Clear();
                return;
            }

            readDatas.RemoveRange(0, langth);

        }
        //读取数据，返true datas中有数据
        public bool read(ref byte[] datas)
        {
            if (readDatas.Count < datas.Length)
                return false;

            for (int i = 0; i < datas.Length; i++)
                datas[i] = (byte)readDatas[i];

            readDatas.RemoveRange(0, datas.Length);
            return true;
        }


        //发生错误
        private void HandleErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            Debug.LogError(e.EventType);
        }

        //关闭连接
        public void Close()
        {
            if (isDebug)
                Debug.Log("Debug mode ->SeralPort   Close " + name);

            isEnter = false;


            if (recvThread != null)
                recvThread.Abort();


            if (sp == null)
                return;

            sp.ErrorReceived -= HandleErrorReceived;

            if (sp.IsOpen)
            {
                sp.DiscardInBuffer();
                sp.DiscardOutBuffer();
                sp.Close();
                // sp.Dispose ();
            }

            sp = null;
        }

        /// <summary>
        /// 打开所有侦听器
        /// </summary>
        public static void OpenAll()
        {
            foreach (var item in seralPorCs)
                item.Value.open();
        }

        /// <summary>
        /// 关闭所有接口
        /// </summary>
        public static void CloseALL()
        {

            foreach (var item in seralPorCs)
                item.Value.Close();

            seralPorCs.Clear();

        }


        /// <summary>
        /// 关闭接口并销毁
        /// </summary>
        public void toDestroy()
        {
            seralPorCs.Remove(name);
            Close();
        }


        //缓存数据
        private ArrayList readDatas = new ArrayList();
        //读取缓存数长度 当使用大数据传输时可以适当加大缓存区加快效率，
        // 缓存区与传输数据包速度相关，过大或过小都会影响效率
        private int ReadBuff = 50;

        /// <summary>
        /// 从 com 口 读取数据
        /// </summary>
        public void ToReceiveData()
        {

            if (!sp.IsOpen)
                return;

            lock (lockObject)
            {
                byte[] buff = new byte[ReadBuff];
                int a = sp.Read(buff, 0, buff.Length);
                if (a < 1)
                    return;


                byte[] nbuff = new byte[a];
                Array.Copy(buff, nbuff, a);
                readDatas.AddRange(nbuff);
            }

            runFiter();

        }


        List<OutputData> sendDatalist = new List<OutputData>();
        ArrayList writerDatas = new ArrayList();
        private object locksend = new object();


        /// <summary>
        /// 添加一个发送数据
        /// </summary>
        /// <param name="data"></param>
        public void addSend(OutputData data)
        {
            lock (locksend)
            {
                //是否有重复发送，把数据叠加到一个发送请求
                foreach (var s in sendDatalist)
                {
                    if (s.name == data.name)
                    {
                        if ((s.mode & OutputData.SendMode.callbackMode) == OutputData.SendMode.callbackMode)
                        {
                            s.addSendNumber(data.sendNumber);
                            return;
                        }
                        s.InitOutData(data);
                        return;
                    }
                }

                //加入到发送请求中
                sendDatalist.Add(data);
            }

        }


        /// <summary>
        /// 移除
        /// </summary>
        /// <param name="name"></param>
        public void remove(string name)
        {
            lock (locksend)
                for (int i = sendDatalist.Count - 1; i >= 0; i--)
                    if (sendDatalist[i].name == name)
                        sendDatalist.Remove(sendDatalist[i]);

        }

        /// <summary>
        /// 停止操作
        /// </summary>
        /// <param name="name"></param>
        public void stopSendData(string name)
        {
            for (int i = sendDatalist.Count - 1; i >= 0; i--)
                if (sendDatalist[i].name == name)
                    sendDatalist[i].isEnter = false;

        }

        public void runSendData()
        {

            byte[] cdata = null;
            if (sendDatalist.Count < 1)
                return;

            // Debug.Log(" send obiect：　" + sendDatalist.Count);

            lock (locksend)
                for (int i = sendDatalist.Count - 1; i >= 0; i--)
                {
                    //Debug.Log(" send  item：　" + sendDatalist[i].name);
                    var outdata = sendDatalist[i];

                    //无效 ,己发送完成
                    if (!outdata.isEnter)
                    {
                        // Debug.Log("end  >>>>>>>>>>>>" + outdata.isEnd + ":" + outdata.EndDataName);
                        //是否有结束数据
                        if (outdata.isEnd && outdata.EndData != null)
                            addSend(outdata.EndData);

                        //移出队列
                        sendDatalist.Remove(sendDatalist[i]);

                        //没有结束命令
                        if (!outdata.isEnd)
                            continue;
                    }

                    byte[] datas = outdata.popDatas();

                    //独占
                    if ((outdata.mode & OutputData.SendMode.onlyMode) == OutputData.SendMode.onlyMode)
                    {

                        com_sendDatas(datas);
                        return;
                    }
                    //单条
                    if ((outdata.mode & OutputData.SendMode.oneMode) == OutputData.SendMode.oneMode)
                    {
                        com_sendDatas(datas);
                    }
                    //合并
                    if ((outdata.mode & OutputData.SendMode.combineMode) == OutputData.SendMode.combineMode)
                    {

                        if (cdata == null)
                            cdata = datas;
                        else
                            cdata = OutputData.mergebytes(cdata, datas);
                    }

                }


            if (cdata != null)
                com_sendDatas(cdata);


        }


        /// <summary>
        /// 通过设置 writerDatas 数据   public void write(byte[] datas)
        /// 发送线程自动发送让发送数据
        /// </summary>
        public void ToSendData()
        {
            while (writerDatas.Count > 0)
            {
                com_sendDatas((byte[])writerDatas[0]);
                writerDatas.RemoveAt(0);
            }
        }




        /// <summary>
        /// 让设备发出数据
        /// </summary>
        /// <param name="datas"></param>
        void com_sendDatas(byte[] datas)
        {
               if (!sp.IsOpen)
                return;
                
            //强制开启加入校验数据
            if ((dataFormatType & (byte)FormatType.SendParity) == (byte)FormatType.SendParity)
            {
                if (DataFormatSendParity == "CRC_HL")
                    datas = (byte[])CrcHelper.To_Crc16_Bytes(datas,true);

                else if(DataFormatSendParity == "CRC_LH")
                  datas = (byte[])CrcHelper.To_Crc16_Bytes(datas,false);
            }

            if (isDebug)
                Debug.LogWarning("[KF Debug mode] -> com " + name + " send datas:" + DataFiter.DataString(datas));

            if (datas == null)
                return;
         

            lock (lockObject)
                sp.Write(datas, 0, datas.Length);

        }

        //发出信号
        public delegate void EventListener(DataFiter fiter);
        //侦听者
        EventListener OnDatas;

        /// <summary>
        /// 清空侦听器
        /// </summary>
        public void clienListener()
        {
            OnDatas = null;
        }
        /// <summary>
        /// 设置侦听者
        /// </summary>
        /// <param name="listener"></param>
        public void setListener(EventListener listener)
        {
            OnDatas = listener;
        }
        /// <summary>
        /// 添加一个侦听者
        /// </summary>
        /// <param name="listener"></param>
        public void addListener(EventListener listener)
        {
            OnDatas += listener;
        }
        /// <summary>
        /// 移除侦听者
        /// </summary>
        /// <param name="listener"></param>
        public void removeListener(EventListener listener)
        {
            OnDatas -= listener;
        }


        //线程锁
        private object lockObject = new object();
        //收发数据线程 
        private Thread recvThread;

        /// <summary>
        /// 子线程运行，
        /// 使用线程不堵主线程运行
        /// </summary>
        private void threadRead()
        {
            while (isEnter)
            {
                try
                {

                    //发送
                    ToSendData();
                    runSendData();

                    //接收
                    ToReceiveData();
                }
                catch (Exception e)
                {
                    if (isDebug)
                        Debug.Log("【KF Debug mode】 -> SeralPortd:" + name + "》 接口 " + comName + ":读取异常，如果是超时属正常现像，如果数据没有正确读取，检查一下确保设备连接没有问题。异常信息：" + e.ToString());
                    Thread.Sleep(100);
                }
            }
        }

        //启动读写线程
        public void ThreadInit()
        {
            ReaderThread();
        }
        //创建线程用于接收串口数据  
        private void ReaderThread()
        {
            if (recvThread != null)
                recvThread.Abort();

            recvThread = new Thread(threadRead);
            recvThread.IsBackground = true;
            //recvThread.Priority = System.Threading.ThreadPriority.AboveNormal;
            recvThread.Start();
        }



        private object lockQueue = new object();
        //接收信息过虑器
        List<DataFiter> readfiters = new List<DataFiter>();
        //事件队列
        List<DataFiter> datasQueue = new List<DataFiter>();

        /// <summary>
        /// 移除事件器 提供接口功能
        /// </summary>
        /// <param name="name"></param>
        public void removeFiter(string name)
        {
            for (int i = 0; i < readfiters.Count; i++)
                if (readfiters[i].name == name)
                    readfiters.Remove(readfiters[i]);

        }
        /// <summary>
        /// 添加事件，过读取过虑器
        /// 不对重复的事件进行添加
        /// </summary>
        /// <param name="fiter"></param>
        public void addFiter(DataFiter fiter)
        {
            foreach (var item in readfiters)
                if (item.isName(fiter.name))
                    return;

            readfiters.Add(fiter);
        }

        /// <summary>
        ///  运行过虑器，
        /// 检测是否有乎合的数据转换成事件
        /// </summary>
        private void runFiter()
        {
            //Debug.Log("read one peer ");
            //数据正确的开始
            byte startbyte = new byte();
            if (!checkData(ref startbyte))
                return;
           // Debug.Log("read one peer 1");
            //是否有开始符
            if ((dataFormatType & (byte)FormatType.FixedStart) == (byte)FormatType.FixedStart)
                if (DataFormatStart != startbyte)
                {
                    //跳过一个byte
                    skipDatas();
                    return;
                }
           // Debug.Log("read one peer 2");
            //收到的数据为byte 
            byte[] buf = new byte[1];
            //数据中是否包函长度值，通常数据是不固定长度的
            if ((dataFormatType & (byte)FormatType.EnvelopeLength) == (byte)FormatType.EnvelopeLength)
            {
                byte lg = new byte();
                //读不到长度值
                if (!checkData(ref lg, DataFormatSizeIndex))
                    return;
                buf = new byte[lg];
            }
            else if ((dataFormatType & (byte)FormatType.FixedLength) == (byte)FormatType.FixedLength)
            {
                //固定长度
                buf = new byte[DataFormatLangth];
            }
            else
            {
                Debug.LogError("SeralPort  config error 需要设置读取数据的长度方案，配置中需要设定数据 FormatType 固定长度或从数据中读取");
                clearDatas();
                return;
            }
           // Debug.Log("read one peer 3");
            //没有读取完整
            if (!read(ref buf))
                return;

            //结束符 结束符不正确数据不符合法 
            if ((dataFormatType & (byte)FormatType.FixedEnd) == (byte)FormatType.FixedEnd)
                if (buf[buf.Length - 1] != DataFormatEnd)
                    return;

            //校验数据
            //if ((dataFormatType & (byte)FormatType.EnvelopeCRC) == (byte)FormatType.EnvelopeCRC)

            if (isDebug)
                        Debug.Log("[KF Debug mode] -> RECEIVE  one length:" + readfiters.Count ) ;

       
            //事件数据过虑器
            for (int i = 0; i < readfiters.Count; i++)
                if (readfiters[i].filter(buf))
                {
                    if (isDebug)
                        Debug.Log("[KF Debug mode] -> RECEIVE one fiter " + readfiters.Count + " datas:" + readfiters[i].name + ":" + readfiters[i].ischeck + ":" + DataFiter.DataString(buf));

                    onFilter(readfiters[i].CloneObject());
                }
        }


        /// <summary>
        /// 发出过虑器事件
        /// 把事件推送到主线程队列中
        /// </summary>
        /// <param name="fiter"></param>
        private void onFilter(DataFiter fiter)
        {
            //发送数据中有回调处理计数
            foreach (var a in sendDatalist)
                if (a != null && a.isEnd && !a.onCallBackFiter(fiter))
                {
                    //com_sendDatas(a.tempdats);
                }


            //存入事件队列 使用同步锁与主线程交互
            lock (lockQueue)
                datasQueue.Add(fiter);
        }



        /// <summary>
        /// 由主unity 主线程处理
        /// 推送到游戏应用 实制使用到业务驱动
        /// </summary>
        public void update()
        {
            if (OnDatas == null)
                return;

            //缓冲
            List<DataFiter> fiter = new List<DataFiter>();

            //从线程拷贝出来 防止主线程处理时间过长影响接收线程
            lock (lockQueue)
            {
                foreach (var a in datasQueue)
                    fiter.Add(a);
                datasQueue.Clear();
            }

            //由主线程推送信息
            foreach (var b in fiter)
            {
                OnDatas.Invoke(b);
            }

        }
    }
}
